package com.wjbgn.bsolver.gateway.controller;

import cn.hutool.crypto.digest.MD5;
import com.wjbgn.bsolver.gateway.client.dto.UserDTO;
import com.wjbgn.bsolver.gateway.util.dto.Result;
import com.wjbgn.bsolver.gateway.util.jwt.JwtUtil;
import com.wjbgn.bsolver.gateway.util.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.Objects;

/**
 * description: 登录controller
 *
 * @author: weirx
 * @time: 2021/3/29 9:36
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class LoginController {
    private final static String USER_VALIDATE_PATH = "http://bsolver-user/user/validateUser";

    private static final String TOPIC_PREFIX = "MESSAGE_";

    @Autowired
    private WebClient.Builder webClientBuilder;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 登录
     *
     * @param userDTO
     * @return com.wjbgn.bsolver.gateway.util.dto.Result
     * @author weirx
     * @date: 2022/3/14
     */
    @PostMapping("/login")
    public Result login(@RequestBody UserDTO userDTO,@RequestHeader HttpHeaders headers) {
        if (null == headers.get("murmur") ){
            return Result.failed("[LoginController.login]murmur为空");
        }
        // 密码md5加密
        userDTO.setPassword(MD5.create().digestHex(userDTO.getPassword()));
        // Webclient调用接口
        Mono<Boolean> monoInfo = webClientBuilder
                .build().post().uri(USER_VALIDATE_PATH)
                .body(BodyInserters.fromValue(userDTO)).header(HttpHeaders.CONTENT_TYPE, "application/json")
                .retrieve().bodyToMono(Boolean.class);
        // 异步监听
        monoInfo.subscribe(data -> {
            ResultToFront(data, userDTO.getUsername(),headers.get("murmur").get(0));
        });

        return Result.success();
    }

    /**
     * 处理登录结果
     * @param result
     * @param username
     * @param murmur
     * @author weirx
     * @return void
     * @date: 2022/3/23
     */
    private void ResultToFront(Boolean result, String username,String murmur) {
        // 获取结果，此处才会抛出异常
        if (result) {
            // 用户存在，直接生成token，登录成功n
            String token = JwtUtil.generateToken(username);
            // 将token放入redis
            redisUtil.setObjectExpire(JwtUtil.REDIS_TOKEN_PREFIX + username, token, Duration.ofMinutes(JwtUtil.REDIS_TOKEN_EXPIRE_MINUTE));
            redisUtil.publish(TOPIC_PREFIX + murmur, Result.success(new UserDTO(username, token)));
        } else {
            redisUtil.publish(TOPIC_PREFIX + murmur, Result.failed("用户名不存在或密码错误"));
        }
    }

    /**
     * 登出接口
     *
     * @param
     * @return com.wjbgn.bsolver.gateway.util.dto.Result
     * @author weirx
     * @date: 2022/3/14
     */
    @PostMapping("/logout")
    public Result<String> logout(@RequestBody UserDTO userDTO) {
        Boolean b = redisUtil.deleteObject(JwtUtil.REDIS_TOKEN_PREFIX + userDTO.getUsername());
        if (!b) {
            return Result.failed("登出失败");
        }
        return Result.success("登出成功");
    }
}